﻿using System;
using System.Threading;
using Sharp.Domain.PlatformBoundedContext.WorkFlowModule.Aggregates;
using Sharp.Domain.PlatformBoundedContext.WorkFlowModule.Engine.Common;
using Sharp.Domain.Repositories;
using Sharp.Infrastructure;
using Sharp.Infrastructure.IoC;

//using Slickflow.Engine.Business.Data;


namespace Sharp.Application.Platform.WorkflowService
{
    public interface ILogManager
    {
        /// <summary>
        /// 插入流程日志数据
        /// </summary>
        /// <param name="entity"></param>
        void Insert(object entity);
    
        /// <summary>
        /// 记录流程异常日志
        /// </summary>
        /// <param name="entity"></param>
        void Record(string title, 
            LogEventType eventType, 
            LogPriority priority, 
            object extraObject,
            System.Exception e);
    }

    /// <summary>
    /// 日志处理记录类
    /// </summary>
    public class LogManager : ILogManager 
    {
        private ILogEntityRepository _logEntityRepository;

        public LogManager(IRepositoryContext context, ILogEntityRepository logEntityRepository)
        {
            _logEntityRepository = logEntityRepository;
        }

        #region 新增、更新和删除流程数据
        /// <summary>
        /// 记录流程异常日志
        /// </summary>
        /// <param name="entity"></param>
        public void Record(string title, 
            LogEventType eventType, 
            LogPriority priority, 
            object extraObject,
            System.Exception e)
        {
            try
            {
                var log = new LogEntity();
                log.EventTypeID = (int)eventType;
                log.Priority = (int)priority;
                log.Severity = priority.ToString().ToUpper();
                log.Title = title;
                log.Timestamp = DateTime.Now;
                log.Message = e.Message;
                log.StackTrace = e.StackTrace.Length > 4000 ? e.StackTrace.Substring(0, 4000): e.StackTrace;
                if (e.InnerException != null)
                {
                    log.InnerStackTrace = e.InnerException.StackTrace.Length > 4000 ? 
                        e.InnerException.StackTrace.Substring(0, 4000) : e.InnerException.StackTrace;
                }

                if (extraObject != null)
                {
                    var jsonData = SerializableHelper.SerializeToString(extraObject, DataFormart.Xml);
                    log.RequestData = jsonData.Length > 2000 ? jsonData.Substring(0, 2000) : jsonData;
                }

                //线程池添加日志记录
                ThreadPool.QueueUserWorkItem(new WaitCallback(Insert), log);
            }
            catch
            {
                //如果记录日志发生异常，不做处理
                ;
            }
        }

        /// <summary>
        /// 插入流程日志数据
        /// </summary>
        /// <param name="entity"></param>
        public void Insert(object entity)
        { 
                var log = (LogEntity)entity;
            _logEntityRepository.Add(log);
            _logEntityRepository.Context.Commit();


        }
        #endregion

        #region 静态方法
        public static void RecordLog(string title, 
            LogEventType eventType, 
            LogPriority priority, 
            object extraObject,
            System.Exception e)
        {
            var lm = ServiceLocator.Instance.GetService<ILogManager>(); 
            lm.Record(title, eventType, priority, extraObject, e);
        }
        #endregion
    }
}
